package controller

import (
	"fmt"
	"net/http"
	"strings"
	"time"

	"github.com/labstack/echo"
	"gopkg.in/mgo.v2/bson"

	"m-project-admin/app/entity"
	"m-project-admin/app/manager"
	"m-project-admin/app/model"
	"m-project-admin/app/utils"
)

// AddApp
func AddApp(c echo.Context) error {
	loginAdminInfo := manager.GetLoginAdminInfo(&c)

	data := make(map[string]interface{})
	data["loginAdminInfo"] = loginAdminInfo
	data["env_desc"] = utils.GetEnvDesc()
	return c.Render(http.StatusOK, "add_app.html", data)
}

// HomeList
func HomeList(c echo.Context) error {
	loginAdminInfo := manager.GetLoginAdminInfo(&c)

	id := c.QueryParam("id")
	appName := c.QueryParam("app_name")

	skip, page := utils.GetSkipPage(utils.PageCount, c)

	// 查询模板列表
	count, _ := manager.GetAppCount(id, appName)
	apps, _ := manager.GetAppList(id, appName, skip, utils.PageCount)
	var appList []map[string]interface{}
	for _, row := range apps {
		item := formatApp(row)
		appList = append(appList, item)
	}

	res := utils.Paginator(page, utils.PageCount, count)

	linkPrefix, query := getAppLinkPrefixQuery("/appList?", id, appName)

	// 渲染结果到模板
	data := make(map[string]interface{})
	data["appList"] = appList
	data["paginator"] = res
	data["linkPrefix"] = linkPrefix
	data["total"] = count
	data["loginAdminInfo"] = loginAdminInfo
	data["query"] = query
	data["env_desc"] = utils.GetEnvDesc()
	return c.Render(http.StatusOK, "app_list.html", data)
}

// UpdateApp
func UpdateApp(c echo.Context) error {
	loginAdminInfo := manager.GetLoginAdminInfo(&c)

	id := c.QueryParam("id")
	if id == "" {
		data := make(map[string]interface{})
		data["error_content"] = "😞请选择要修改的App😞"
		data["loginAdminInfo"] = loginAdminInfo
		data["env_desc"] = utils.GetEnvDesc()
		return c.Render(http.StatusOK, "error.html", data)
	}

	// 查询用户信息
	appItem, _, _ := manager.GetAppById(id)
	if appItem.Id.Hex() == "" {
		data := make(map[string]interface{})
		data["error_content"] = "😞要修改的App数据不存在😞"
		data["loginAdminInfo"] = loginAdminInfo
		data["env_desc"] = utils.GetEnvDesc()
		return c.Render(http.StatusOK, "error.html", data)
	}

	// 渲染结果到模板
	data := make(map[string]interface{})
	data["appInfo"] = formatApp(appItem)
	data["loginAdminInfo"] = loginAdminInfo
	data["env_desc"] = utils.GetEnvDesc()
	return c.Render(http.StatusOK, "update_app.html", data)
}

// DoAddApp
func DoAddApp(c echo.Context) error {
	appName := strings.TrimSpace(c.FormValue("app_name"))
	callbackUrl := strings.TrimSpace(c.FormValue("callback_url"))

	if appName == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "APP名称不能为空"})
	}
	if callbackUrl == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "回调地址不能为空"})
	}

	// 判断App Name是否存在
	_, b, err := manager.GetAppByName(appName)
	if b {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "该APP名称已存在"})
	}

	appKey := utils.Sha1s([]byte(fmt.Sprintf("%s%d", appName, time.Now().Unix())))
	appSecret := utils.Sha1s([]byte(fmt.Sprintf("%s%d", appName, time.Now().Unix()+1)))

	appItem := model.App{
		Id:           bson.NewObjectId(),
		App_name:     appName,
		Callback_url: callbackUrl,
		App_key:      appKey,
		App_secret:   appSecret,
		Adminid:      manager.GetCurrentAdminId(&c),
		Status:       0,
		Create_time:  time.Now().Unix(),
		Update_time:  time.Now().Unix(),
	}
	_, err = manager.SaveApp(appItem)
	if err != nil {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: err.Error()})
	}

	return c.JSON(http.StatusOK, entity.Response{En: 200, Em: "成功"})
}

// DoUpdateApp
func DoUpdateApp(c echo.Context) error {
	id := c.FormValue("id")
	if id == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "请选择要修改的App"})
	}

	appName := strings.TrimSpace(c.FormValue("app_name"))
	callbackUrl := strings.TrimSpace(c.FormValue("callback_url"))

	if appName == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "App名称不能为空"})
	}
	if callbackUrl == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "回调地址不能为空"})
	}

	// 检查模板名称是否重复
	exAppItem, _, _ := manager.GetAppByName(appName)
	if (exAppItem.Id.Hex() != "") && (exAppItem.Id.Hex() != id) {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "该App名称已存在"})
	}

	appItem := make(map[string]interface{})
	appItem["app_name"] = appName
	appItem["callback_url"] = callbackUrl
	appItem["update_time"] = time.Now().Unix()

	_, err := manager.UpdateApp(id, appItem)
	if err != nil {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: err.Error()})
	}

	return c.JSON(http.StatusOK, entity.Response{En: 200, Em: "成功"})
}

// DoDeleteApp
func DoDeleteApp(c echo.Context) error {
	dataid := c.FormValue("id")

	if dataid == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "请选择要删除的App"})
	}

	appItem, _, err := manager.GetAppById(dataid)
	if err != nil {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "数据错误"})
	}
	if appItem.Id.Hex() != dataid {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "数据错误"})
	}

	adminId := manager.GetCurrentAdminId(&c)

	// 只能删除自己创建的app
	if appItem.Adminid != adminId {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "您没权限删除"})
	}

	// 物理删除App
	b, err := manager.DeleteApp(dataid)
	if b == false {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: err.Error()})
	}

	return c.JSON(http.StatusOK, entity.Response{En: 200, Em: "成功"})
}

// DoDeleteAppBatch
func DoDeleteAppBatch(c echo.Context) error {
	dataids := c.FormValue("ids")

	if dataids == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "请选择要删除的App"})
	}

	dataidsArray := strings.Split(dataids, ",")

	for _, dataid := range dataidsArray {
		appItem, _, err := manager.GetAppById(dataid)
		if err != nil {
			return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "数据错误"})
		}
		if appItem.Id.Hex() != dataid {
			return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "数据错误"})
		}

		adminId := manager.GetCurrentAdminId(&c)

		// 只能删除自己创建的app
		if appItem.Adminid != adminId {
			return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "您没权限删除"})
		}

		// 物理删除App
		b, err := manager.DeleteApp(dataid)
		if b == false {
			return c.JSON(http.StatusOK, entity.Response{En: 402, Em: err.Error()})
		}
	}
	return c.JSON(http.StatusOK, entity.Response{En: 200, Em: "成功"})
}

func formatApp(app model.App) map[string]interface{} {
	// 取创建人姓名
	admin, _, _ := manager.GetAdminById(app.Adminid)
	adminName := ""
	if admin.Id.Hex() != "" {
		adminName = admin.Name
	}

	item := make(map[string]interface{})

	item["id"] = app.Id.Hex()
	item["app_name"] = app.App_name
	item["adminid"] = app.Adminid
	item["admin_name"] = adminName
	item["callback_url"] = app.Callback_url
	item["app_key"] = app.App_key
	item["app_secret"] = app.App_secret
	item["status"] = app.Status
	item["create_date"] = time.Unix(app.Create_time, 0).Format("2006-01-02 15:04:05")
	item["update_date"] = time.Unix(app.Update_time, 0).Format("2006-01-02 15:04:05")

	return item
}

func getAppLinkPrefixQuery(linkPrefix string, appId string, appName string) (string, map[string]interface{}) {
	query := make(map[string]interface{})
	if appId != "" {
		query["id"] = appId
		linkPrefix += fmt.Sprintf("id=%s&", appId)
	}
	if appName != "" {
		query["app_name"] = appName
		linkPrefix += fmt.Sprintf("app_name=%s&", appName)
	}

	return linkPrefix, query
}
